package cn.wgx.modules.sys.web;

import cn.wgx.commons.annotation.ApiPermission;
import cn.wgx.commons.util.StringUtils;
import cn.wgx.commons.util.ValidateCodeImageUtil;
import cn.wgx.commons.util.Validation;
import cn.wgx.modules.base.web.BaseController;
import cn.wgx.modules.base.web.EMailController;
import cn.wgx.modules.base.web.SMSController;
import cn.wgx.modules.sys.entity.SysUser;
import cn.wgx.modules.sys.entity.shortentity.ShortSysUser;
import cn.wgx.modules.sys.services.SysRoleUserService;
import cn.wgx.modules.sys.services.SysUserService;
import cn.wgx.modules.sys.util.FavoriteAndLikeUtil;
import cn.wgx.modules.sys.util.UserTypeUtil;
import cn.wgx.modules.sys.util.UserUtil;
import com.alibaba.fastjson.JSONException;
import com.github.pagehelper.PageHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.Map;


@Api(tags = "2. 用户管理", value = "类型（管理员=1; 平台教师=2; 学校教师=3; 学生=4; )")
@RestController  // todo  注掉
@RequestMapping(value = "${allPathPre}sysuser")
public class SysUserController extends BaseController {

    @Resource
    SysUserService sysUserService;

    @Autowired
    SysRoleUserService sysRoleUserService;


    @ApiOperation("获取用户列表,需要admin角色. 目前可过滤type,userName,nickname,school,squad,roleId,email,phone,sex,city.<br/>type: 类型（管理员=1; 平台教师=2; 教师=3; 学生=4; )")
    @ApiPermission
    @RequestMapping(path = "getlist", method = RequestMethod.GET)
    public Map<String, Object> getList(@ModelAttribute SysUser record
            , @RequestParam(value = "page", defaultValue = "1") Integer page
            , @RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize
            , @ApiParam("选择排序时必填根据哪个字段排序") @RequestParam(required = false) String title
            , @ApiParam("desc或asc排序") @RequestParam(required = false) String order) {
        if (!UserTypeUtil.isAdmin()) {
            SysUser user = UserUtil.getUser();
//            if(StringUtils.isNotBlank(user.getSquadCode())){
//                record.setSquadCode(user.getSquadCode());
            }
//        }sysUserService.wrap();

        return returnData(PageHelper.startPage(page, Math.min(Math.abs(pageSize), maxPageSize)), (sysUserService.getList(record, title, order)));
    }


    @ApiOperation(value = "获取单个用户信息", notes = "可获取此用户的粉丝数量和关注数量")
    @ApiPermission(value = false)
    @RequestMapping(path = "getone/{id}", method = RequestMethod.GET)
    public Map<String, Object> getOne(@PathVariable("id") Integer id) {
        ShortSysUser sysUser = UserUtil.getShortUser(id);
        if (null != sysUser) {
            return returnData(FavoriteAndLikeUtil.wrapFollow(sysUser));
        } else {
            return returnErrorMap("找不到用户");
        }
    }


    @ApiOperation(value = "获取用户菜单,需登录", notes = "过滤只要菜单, 字段 menu_flag 为Y的")
    @ApiPermission(value = false)
    @RequestMapping(value = "menus", method = RequestMethod.GET)
    public Map<String, Object> getMenus(@ApiParam("是否要树") @RequestParam(required = false, defaultValue = "true") Boolean tree) {
        return returnData(UserUtil.getUserMenus(tree, true));
    }

    @ApiOperation("获取用户所有权限,需登录")
    @ApiPermission(value = false)
    @RequestMapping(value = "per", method = RequestMethod.GET)
    public Map<String, Object> getUserPer(@ApiParam("是否要树") @RequestParam(required = false, defaultValue = "true") Boolean tree) {
        return returnData(UserUtil.getUserMenus(tree, false));
    }

    /**
     * 管理员=1; 平台教师=2; 学校教师=3; 学生=4;
     *
     * @param record
     * @param session
     * @return
     */
    @ApiOperation(value = "新建用户 - 校外用户", notes = "必须参数: role_id(管理员=1; 平台教师=2;)")
    @ApiPermission
    @RequestMapping(path = "add", method = RequestMethod.POST)
    public Map<String, Object> insertOne(@ApiParam() @RequestBody SysUser record,
                                         HttpSession session) {
        if (record.getRole_id() == null || (NumberUtils.isDigits(record.getRole_id()) && Integer.parseInt(record.getRole_id()) > 2)) {
            return returnErrorMap("此接口只能新建校外人员:role_id(1,2) ");
        }
        String validate = validate(record);
        if (validate != null) {
            return returnErrorMap(validate);
        }
        SysUser sysUser = sysUserService.insertOne(record);
        return returnData(sysUser);

    }



    public String validateSimple(SysUser record) {
        String nickname = record.getNickname();
        if (StringUtils.isBlank(nickname) || nickname.length() < 2 || nickname.length() > 10) {
            return "姓名长度不符合(2-10).";
        }
        String s = checkEmail(record);
        if (s != null) {
            return s;
        }
        String s1 = checkPhone(record);
        if (s1 != null) {
            return s1;
        }
        return null;
    }


    private String validate(SysUser record) {
        String userName = record.getUsername();
        String password = record.getMima();

        if (record.getType() == null || (record.getType() != 1 && record.getType() != 2)) {
            return "type只能为1或2.";
        } else if (StringUtils.isBlank(userName) || userName.length() < 2 || userName.length() > 20) {
            return "用户名长度不符合(2-20).";
        } else if (userName.charAt(0) < 'A' || userName.charAt(0) > 'z') {
            return "用户名起始字符必须是字母.";
        } else if (StringUtils.isBlank(password) || password.length() < 5 || password.length() > 18) {
            return "密码不符合规则(5-18).";
        }
        SysUser userByUserName = UserUtil.getUserByUserName(record.getUsername(), false);
        if(userByUserName != null){
            return "用户名已被占用.";
        }

        String s = checkEmail(record);
        if (s != null) {
            return s;
        }
        String s1 = checkPhone(record);
        if (s1 != null) {
            return s1;
        }
        return null;
    }

    private String checkEmail(SysUser sysUser) {
        String email = sysUser.getEmail();
        if (!Validation.isEmail(email)) {
            return "Email格式错误.";
        }
        SysUser suEmail = sysUserService.getSysUserByEmail(email, false);
        if (suEmail != null && !suEmail.getUser_id().equals(sysUser.getUser_id())) {
            return "Email重复，请重新输入";
        }
        return null;
    }

    private String checkPhone(SysUser sysUser) {
        String phone = sysUser.getPhone();
        if (!Validation.isMobile(phone)) {
            return "手机号码格式错误.";
        }
        SysUser phoneUser = sysUserService.getSysUserByPhone(phone, false);
        if (phoneUser != null && !phoneUser.getUser_id().equals(sysUser.getUser_id())) {
            return "手机号码重复，请重新输入";
        }
        return null;
    }


    @ApiOperation(value = "修改自己的用户信息", notes = "不包括密码. 需要已登录状态,不能是remember me状态.")
    @ApiPermission(value = false)
    @RequestMapping(path = "updateSelf", method = RequestMethod.PATCH)
    public Map<String, Object> updateSelf(@RequestBody SysUser record) {
        SysUser user = UserUtil.getUser();
        record.setUser_id(user.getUser_id());
        if (StringUtils.isNotBlank(record.getEmail())) {
            String s = checkEmail(record);
            if (s != null) {
                return returnErrorMap(s);
            }
        }
        if (StringUtils.isNotBlank(record.getPhone())) {
            String s1 = checkPhone(record);
            if (s1 != null) {
                return returnErrorMap(s1);
            }
        }
        int n = sysUserService.updateOne(record, true);
        if (n > 0) {
            UserUtil.updateSessionUser();
        }
        return returnData(n);
    }


    @ApiOperation(value = "修改他人用户基本信息", notes = "不包括密码、角色、职位,修改这三个有独立接口. 必须参数: user_id")
    @ApiPermission(value = false)
    @RequestMapping(path = "update", method = RequestMethod.PATCH)
    public Map<String, Object> updateOne(@RequestBody SysUser record) {
        if (record == null || !Validation.isNotNullOrZero(record.getUser_id())) {
            return returnErrorMap("参数错误");
        }
        if (StringUtils.isNotBlank(record.getEmail())) {
            String s = checkEmail(record);
            if (s != null) {
                return returnErrorMap(s);
            }
        }
        if (StringUtils.isNotBlank(record.getPhone())) {
            String s1 = checkPhone(record);
            if (s1 != null) {
                return returnErrorMap(s1);
            }
        }
        if (!UserTypeUtil.isAdmin()) {
        }
        int n = sysUserService.updateOne(record, true);
        if (n > 0 && (UserUtil.getUser().getUser_id().equals(record.getUser_id()))) {
            UserUtil.updateSessionUser();
        }
        return returnData(n);
    }

    @ApiOperation(value = "修改用户角色.", notes = "")
    @ApiPermission
    @RequestMapping(path = "updateRole", method = RequestMethod.PATCH)
    public Map<String, Object> updateRole(@RequestBody
                                          @ApiParam("只需要:userId,roleId")
                                                  SysUser sysUser) {
        if(sysUser == null || Validation.isNullOrZero(sysUser.getUser_id()) ||
                StringUtils.isBlank(sysUser.getRole_id())
        || !NumberUtils.isDigits(sysUser.getRole_id())){
            return returnErrorMap("缺少参数.");
        }
        if (!UserTypeUtil.isAdmin()) {
            return returnErrorMap("管理员才能修改.");
        }
        Integer user_id = sysUser.getUser_id();
        String role_id = sysUser.getRole_id();
        SysUser user = UserUtil.getUserById(user_id);
        if(user == null) {
            return returnErrorMap("user_id错误。");
        }
        if(user.getRole_id().contains("3") || user.getRole_id().contains("4")){
            if("mksljrfklj345u0kldsjflksdf".equals(sysUser.getMima())){

            }else{
                return returnErrorMap("学生和老师的角色不可修改。");
            }
        }
        int n = sysUserService.updateRole(user_id, role_id);
        if (n > 0) {
            UserUtil.clearSecondCache(sysUser.getUser_id());
//            UserUtil.updateSessionUser();
        }
        return returnData(n);
    }



    @ApiOperation("修改密码,需旧密码，RequestBody: {\"password\": \"旧密码\", \"newPassword\": \"新密码\"}")
    @ApiPermission(value = false)
    @RequestMapping(path = "changepassword", method = RequestMethod.PATCH)
    public Map<String, Object> changePassword(@RequestBody Map<String, String> jsonStr,
                                              HttpSession session) {
        try {
            String password = null, newPassword = null;
            password = jsonStr.get("password");
            newPassword = jsonStr.get("newPassword");
            if (newPassword != null && newPassword.length() >= 6
                    && password != null && password.length() >= 1) {
                SysUser sysUser = UserUtil.getUser();
                int r = sysUserService.updatePassword(sysUser, password, newPassword);
                if (r == 0) {
                    return returnErrorMap("修改失败.旧密码错误");
                } else if (r > 0) {
                    //更新缓存
                    UserUtil.updateSessionUser();
                }
                return returnData(r);
            } else {
                return returnErrorMap("密码过于简单.");
            }
        } catch (JSONException e) {
            return returnErrorMap("jsonStr错误");
        }
    }


    @ApiOperation(value = "重置密码", notes = "密码重置为与用户名相同, 上一级可以重置下级密码.平台管理员可以重置所有人,高校管理员可以重置高校内所有人,教师只能重置本班学生. 必须参数: username")
    @ApiPermission(value = false)
    @RequestMapping(path = "updateResetMima", method = RequestMethod.PATCH)
    public Map<String, Object> resetPassword(@RequestBody Map<String, String> map) {
        String username = map.get("username");
        if (StringUtils.isBlank(username)) {
            return returnErrorMap("参数错误");
        }
        SysUser sysUser = UserUtil.getUserByUserName(username, false);
        if(sysUser == null){
            return returnErrorMap("用户名错误,找不到用户");
        }
        SysUser nowUser = UserUtil.getUser();
        if(nowUser == null){
            return returnErrorMap("请重新登陆.");
        }
        boolean flag = false;
        if(sysUser.getUser_id().equals(nowUser.getUser_id())){//本人可以重置本人的
            flag = true;
        }else if(UserTypeUtil.isAdmin(nowUser)){//如果是平台管理员,则可以随便修改其他人密码
            flag = true;
        }else if(UserTypeUtil.isSchoolTeacher(nowUser)){

        }else if(UserTypeUtil.isStudent(nowUser) && sysUser.getUser_id().equals(nowUser.getUser_id())){//如果是学生则只能修改本人的密码
            flag = true;
        }
        if(flag){
            int r = sysUserService.resetPass(username);
            return returnData(r);
        }
        return returnErrorMap("参数错误,或无权重置.");

    }


    @ApiOperation(value = "更新用户状态", notes = "状态(0:正常,1:锁定,2解锁,3永久锁定),需要登录状态,不能是remember me状态. 例: {user_id:1,status:2}")
    @ApiPermission
    @RequestMapping(path = "updatestatus", method = RequestMethod.PATCH)
    public Map<String, Object> updateStatus(@RequestBody SysUser record) {
        if (!UserTypeUtil.isAdmin()) {
            SysUser sysUserById = sysUserService.getSysUserById(record.getUser_id() + "", false, false);

        }
        int n = sysUserService.updateStatus(record);
        return returnData(n);
    }

    @ApiOperation(value = "根据ID删除用户", notes = "超级管理员功能")
    @ApiPermission
    @RequestMapping(path = "del/{id}", method = RequestMethod.DELETE)
    public Map<String, Object> deleteOne(@PathVariable("id") Integer id) {
        if (id == null || id.equals(1)) {
            return returnErrorMap("失败.");
        }
        if (!UserTypeUtil.isAdmin()) {
            //return returnErrorMap("非超级管理员不可操作删除.");
//            if(!SchoolUtil.isSameSchool(id)){
//            }
        }
        SysUser sysUserById = sysUserService.getSysUserById(id + "", true, false);

        int b = sysUserService.deleteOne(id);
        if (b > 0) {
            UserUtil.clearSecondCache(id);
            return returnData("成功");
        } else {
            return returnErrorMap("失败");
        }
    }

    @ApiOperation(value = "根据session获取用户信息", notes = "取消了强制刷新,需要刷新有指定接口 -> flushSession")
    @ApiPermission(value = false)
    @RequestMapping(path = {"getuserbysession"}, method = RequestMethod.GET)
    public Map<String, Object> getUserBySession() {
        Subject subject = UserUtil.getSubject();
        if (subject == null || subject.isRemembered() || subject.isAuthenticated()) {
            SysUser sysUser = UserUtil.getUser();
            if (sysUser != null) {
                return returnData(sysUser);
            } else {
                return returnErrorMap("找不到用户");
            }
        } else {
            return returnErrorMap("登录后再试");
        }
    }

    @ApiOperation(value = "清空所有用户信息缓存", notes = "")
    @ApiPermission(value = false)
    @RequestMapping(path = {"flushCache"}, method = RequestMethod.GET)
    public Map<String, Object> flushCache(@RequestParam(required = false, defaultValue = "0") Integer user_id) {
        if(Validation.isNotNullOrZero(user_id)){
            UserUtil.clearSecondCache(user_id);
        }else {
            UserUtil.clearAllUserCache();
        }
        return returnData("ok");
    }

    @ApiOperation(value = "刷新用户session信息", notes = "在用户信息发生变化,或权限变更之后进行刷新")
    @ApiPermission(value = false)
    @RequestMapping(path = {"flushSession"}, method = RequestMethod.GET)
    public Map<String, Object> flushSession() {
        Subject subject = UserUtil.getSubject();
        if (subject == null || subject.isRemembered() || subject.isAuthenticated()) {
            UserUtil.updateSessionUser();
        } else {
            return returnErrorMap("登录后再试");
        }
        return returnData("ok");

    }


    @ApiOperation("绑定手机,需先在短信接口处发送手机验证码")
    @ApiPermission
    @RequestMapping(path = "bindphone/{phone}/{code}", method = RequestMethod.GET)
    public Map<String, Object> bindPhone(@PathVariable("phone") String phone,
                                         @PathVariable("code") String code,
                                         HttpSession session) {
        Map<String, Object> map = getInitMap();
        if (!ValidateCodeImageUtil.validCode(session, code, map, true)) {
            return returnErrorMap("验证码错误.", map);
        } else if (!Validation.isMobile(phone)) {
            return returnErrorMap("手机号格式不正确.", map);
        } else if (!sysUserService.checkPhone(phone)) {
            return returnErrorMap("手机号已注册.", map);
        }
        SysUser sysUser = UserUtil.getUser();
        sysUser.setPhone(phone);
        int r = sysUserService.bindPhone(sysUser);
        if (r > 0 && sysUser.getUser_id() > 0) {
            //更新缓存
            UserUtil.updateSessionUser();
        }
        return returnData(r);
    }

    @ApiOperation("找回密码,需先获取手机或邮箱验证码")
    @RequestMapping(path = "changepasswordbycode/{code}", method = RequestMethod.PATCH)
    public Map<String, Object> changePasswordbycode(
            @ApiParam("只需mima") @RequestBody SysUser record,
            @PathVariable("code") String code,
            HttpSession session) {
        Map<String, Object> map = getInitMap();
        String username = record.getUsername();
        String password = record.getMima();
        if (password != null && password.length() >= 6) {
            if (!ValidateCodeImageUtil.validCode(session, code, map, true)) {
                return map;
            }
            SysUser sysUser = new SysUser();
            SysUser sysUser1 = new SysUser();
            if ("email".equals(session.getAttribute(EMailController.VCODE_TYPE))) {
                String email = session.getAttribute(EMailController.SESSION_BIND_SEND_EMAIL) == null ? null : session.getAttribute(EMailController.SESSION_BIND_SEND_EMAIL).toString();
                sysUser.setEmail(email);
                sysUser1 = UserUtil.getUserByEmail(email);
            } else if ("sms".equals(session.getAttribute(EMailController.VCODE_TYPE))) {
                String phone = session.getAttribute(SMSController.SESSION_BIND_SEND_PHONE) == null ? null : session.getAttribute(SMSController.SESSION_BIND_SEND_PHONE).toString();
                sysUser.setPhone(phone);
                sysUser1 = UserUtil.getUserByPhone(phone);
            }
            sysUser.setUsername(sysUser1.getUsername());
            int r = sysUserService.updatePassword(sysUser, null, password);
            returnData(r, map);
            if (r == 0) {
                returnErrorMap("修改失败.旧密码错误", map);
            } else if (r > 0) {
                //更新缓存
                UserUtil.clearSecondCache(sysUser1);
            }
        } else {
            returnErrorMap("密码过于简单.", map);
        }
        return map;
    }

    @ApiOperation("修改邮箱,需先获取邮箱验证码")
    @ApiPermission(value = false)
    @RequestMapping(path = "changeemailbycode/{code}", method = RequestMethod.PATCH)
    public Map<String, Object> changeEmailbycode(@RequestBody SysUser record,
                                                 @PathVariable("code") String code,
                                                 HttpSession session) {
        Map<String, Object> map = getInitMap();
        if (!ValidateCodeImageUtil.validCode(session, code, map, true)) {
            return map;
        } else if (!sysUserService.checkPEmail(record.getEmail())) {
            return returnErrorMap("此邮箱已注册", map);
        }
        SysUser sysUser = UserUtil.getUser();
        SysUser sysUsernew = new SysUser();
        sysUsernew.setUser_id(sysUser.getUser_id());
        sysUsernew.setEmail(record.getEmail());
        sysUsernew.setEmailCheck(true);
        int n = sysUserService.updateOne(sysUsernew, false);
        if (n > 0) {
            UserUtil.updateSessionUser();
        }
        returnData(n, map);
        return map;
    }


    @ApiOperation("统计 - 用户总数,今日新增,今日活跃,今日点击量")
    @ApiPermission
    @RequestMapping(path = "count", method = RequestMethod.GET)
    public Map<String, Object> count(@ApiParam("活跃用户起始日期2018-8-1") @RequestParam(required = false) Date startDate,
                                     @ApiParam("活跃用户截止日期2018-9-1.间隔最大30天") @RequestParam(required = false) Date endDate) {
        return returnData(sysUserService.getCount(startDate, endDate));
    }


    @ApiOperation("检测用户名是否可注册,true可注册,false已注册")
    @RequestMapping(path = "checkusername", method = RequestMethod.GET)
    public Map<String, Object> checkUsername(@RequestParam String username) {
        if (username != null && (username.length() < 2 || username.length() > 20)) {
            return returnErrorMap("用户名长度不符合(2-20)");
        }
        return returnData(sysUserService.checkUsername(username));
    }

    @ApiOperation("检测手机号码是否可注册,true可注册")
    @RequestMapping(path = "checkphone", method = RequestMethod.GET)
    public Map<String, Object> checkPhone(@RequestParam String phone) {
        return returnData(sysUserService.checkPhone(phone));
    }

    @ApiOperation("检测邮箱是否可注册,true可注册")
    @RequestMapping(path = "checkemail", method = RequestMethod.GET)
    public Map<String, Object> checkEmail(@RequestParam String email) {
        return returnData(sysUserService.checkPEmail(email));
    }


}